#include <iostream>
#include <string>
#include <cstring>
#include <thread>

#include <nng/nng.h>
#include <nng/protocol/pair0/pair.h>

class MessageCenter
{
public:
    MessageCenter(const std::string &url) : url_(url)
    {
        int rv;
        // 打开 pair 套接字
        rv = nng_pair0_open(&socket_);
        if (rv != 0)
        {
            std::cerr << "Failed to open pair socket: " << nng_strerror(rv) << std::endl;
            return;
        }
        // 客户端连接到服务器
        rv = nng_dial(socket_, url_.c_str(), nullptr, 0);
        if (rv != 0)
        {
            std::cerr << "Failed to dial to " << url_ << ": " << nng_strerror(rv) << std::endl;
            nng_close(socket_);
            return;
        }
        std::cout << "Client connected to " << url_ << std::endl;
    }

    ~MessageCenter()
    {
        nng_close(socket_);
    }

    std::string receiveMessage()
    {
        nng_msg *msg = nullptr;
        int rv = nng_recvmsg(socket_, &msg, 0);
        if (rv != 0)
        {
            std::cerr << "Failed to receive message: " << nng_strerror(rv) << std::endl;
            return "";
        }
        std::string message(reinterpret_cast<char *>(nng_msg_body(msg)), nng_msg_len(msg));
        nng_msg_free(msg);
        return message;
    }

    bool sendMessage(const std::string &message)
    {
        nng_msg *msg = nullptr;
        int rv = nng_msg_alloc(&msg, message.size());
        if (rv != 0)
        {
            std::cerr << "Failed to allocate message: " << nng_strerror(rv) << std::endl;
            return false;
        }
        memcpy(nng_msg_body(msg), message.c_str(), message.size());
        rv = nng_sendmsg(socket_, msg, 0);
        if (rv != 0)
        {
            std::cerr << "Failed to send message: " << nng_strerror(rv) << std::endl;
            nng_msg_free(msg);
            return false;
        }
        return true;
    }

    void close()
    {
        nng_close(socket_);
    }

private:
    std::string url_;
    nng_socket socket_;
};

MessageCenter client("tcp://127.0.0.1:5555");

void sentMessage()
{
    for (int i = 0; i < 10; i++)
    {
        std::string clientMessage = "Hello, server!";
        if (client.sendMessage(clientMessage))
        {
            std::cout << "Client sent message: " << clientMessage << std::endl;
        }
    }

    std::cout << "send thread exited" << std::endl;
}

void receiveMessage()
{
    while (true)
    {
        std::string clientReceivedMessage = client.receiveMessage();
        std::cout << "Client received message: " << clientReceivedMessage << std::endl;
        // if(clientReceivedMessage == ""){
        //     break;
        // }
    }

    std::cout << "receive thread exited" << std::endl;
}

int main()
{
    // std::thread t1(sentMessage);
    // std::thread t2(receiveMessage);
    // t1.detach();
    // t2.join();

    std::this_thread::sleep_for(std::chrono::seconds(3));
    // client.close();

    return 0;
}